#include<stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int data_type;
//声明一个双向链表的结构体类型
typedef struct linkNode
{
	data_type data;//数据域//
	struct linkNode* prior;//指向前驱结点
	struct linkNode* next;//指向后继结点
}linkNode,*pLinklist;
//--------------------------函数声明--------------------------
//创建一个空链表
pLinklist list_Create();
//获得指定位置的结点
pLinklist list_get(pLinklist H, int pos);//通过pos 获得第pos个位置的结点
//判断是否尾空链表
int empty(pLinklist H);
//遍历  双向链表
int list_show(pLinklist H);
//头插
int list_head_insert(pLinklist H, data_type value);
//尾插
int list_tail_insert(pLinklist H, data_type value);
//指定位置插入
int list_insert(pLinklist H, data_type value, int pos);//将value插入到第pos结点之前
//销毁链表
int list_free(pLinklist *H);
//删除某一个位置上的结点
int list_delete(pLinklist H, int pos);
//删除value值所在的结点 dir:0 从后先前遍历  dir:1从前向后遍历
int list_delete_value(pLinklist H,data_type value,int dir);
//修改结点数据  找到原数据  修改为新数据
int list_change_vlaue(pLinklist H,data_type oldvalue,data_type newvalue);
// 向前遍历链表
int list_show_forward(pLinklist H);
// 向后遍历链表
int list_show_back(pLinklist H);

int main(int argc, char const *argv[])
{
    pLinklist head=list_Create();//创建一个空表
 //  //头插
 //  list_head_insert(head,1);
 //  list_head_insert(head,2);
 //  list_head_insert(head,3);
 //  list_head_insert(head,4);
 // // 向前遍历 
 // list_show_forward(head); 
    //尾插
    list_tail_insert(head,5);
    list_tail_insert(head,6);
    list_tail_insert(head,7);
    list_tail_insert(head,8);
    //向后遍历
    list_show_back(head);
    //删除指定位置数据
    list_delete_value(head,3,0);
    list_show_back(head);
    //修改某个值 
    list_change_vlaue(head,1,600);
    list_show_back(head);
    //销毁
    list_free(&head);
    list_show_back(head);
    /* code */
    return 0;
}
//--------------------------函数实现--------------------------
//创建一个空链表
pLinklist list_Create()
{
    pLinklist head=(pLinklist)malloc(sizeof(linkNode));
    if(head==NULL)
    {
        printf("malloc faild\n");
        return NULL;
    }
    head->data=0;
    head->next=head->prior=head;//头结点的前驱结点 和后继结点  都指向头结点   是一个空的双向循环链表
    return head;
    
}
//获得指定位置的结点  //通过pos 获得第pos个位置的结点
pLinklist list_get(pLinklist H, int pos)
{

}
//判断是否尾空链表
int empty(pLinklist H)
{
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
    }
    if(H->next==H&&H->prior==H)
    {
        printf("list is empty\n");
        return 1;
    }
    return 0;
}

//头插
int list_head_insert(pLinklist H, data_type value)
{
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
    }
    //创建一个新结点
    pLinklist newbode=(pLinklist)malloc(sizeof(linkNode));
    if(newbode==NULL)
    {
        printf("newnode is malloc faild\n");
        return -1;
    }
    newbode->data=value;
    newbode->prior=newbode->next=NULL;
    //头插
    newbode->next=H->next;
    H->next->prior=newbode;
    H->next=newbode;
    newbode->prior=H;

    return 0;
}
//尾插
int list_tail_insert(pLinklist H, data_type value)
{
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
    }
    pLinklist phead=H;
    while (phead->next!=H)
    {
        phead=phead->next;
    }
    //phead 就是尾结点
    
    //创建一个新结点
    pLinklist newbode=(pLinklist)malloc(sizeof(linkNode));
    if(newbode==NULL)
    {
        printf("newnode is malloc faild\n");
        return -1;
    }
    newbode->data=value;
    newbode->prior=newbode->next=NULL;
    //修改指针
    H->prior=newbode;
    newbode->prior=phead;
    newbode->next=H;
    phead->next=newbode;
    return 0;

}
//指定位置插入  //将value插入到第pos结点之前
int list_insert(pLinklist H, data_type value, int pos)
{

}
//销毁链表
int list_free(pLinklist *H)
{
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
    }
    pLinklist phead=*H,qhead=(*H)->prior;
    while ((*H)!=qhead)
    {
       *(H)=(*H)->next;//更新头结点
       printf("free data:%d\n",phead->data);
       free(phead);
       phead=NULL;
       phead=(*H);
    }
    printf("*H.data:%d\n",(*H)->data);
    free(*H);
    *H=NULL;
    return 0;
    
}
//删除某一个位置上的结点
int list_delete(pLinklist H, int pos)
{

}
//删除value值所在的结点  dir:0 从后先前遍历  dir:1从前向后遍历
int list_delete_value(pLinklist H,data_type value,int dir)
{
    if(empty(H))//只要不返回0  就表示是为空 或者表不存在
    {
        return -1;
    }
    pLinklist phead=NULL;
    if(dir)//从前向后遍历
    {
        phead=H->next;
        while (value!=phead->data)
        {
            phead=phead->next;
            if(phead==H)
            {
                break;
            }
        }
        //phead不等于H才表示找到了
        if(phead!=H)
        {
            phead->prior->next=phead->next;//将要删除的结点的前驱结点的后继 指向要删除结点的后继结点
            phead->next->prior=phead->prior;//
            free(phead);
            return 0;
        }
        else
        {
            printf("is nodt find\n");
            return -1;
        }
    }
    
    //否则从后向前遍历
    phead=H->prior;
    while (phead!=H)
    {
        if(value==phead->data)
        {
            //删除
            phead->prior->next=phead->next;
            phead->next->prior=phead->prior;
            free(phead);
            return 0;
        }
        phead=phead->prior;
    }
    return -1;
   

}
//修改结点数据  找到原数据  修改为新数据
int list_change_vlaue(pLinklist H,data_type oldvalue,data_type newvalue)
{
    if(empty(H))//只要不返回0  就表示是为空 或者表不存在
    {
        return -1;
    }
    pLinklist phead=H->prior;
    while (phead!=H)
    {
        if(oldvalue==phead->data)
        {
            //修改
            phead->data=newvalue;
            return 0;
        }
        phead=phead->prior;
    }
    return -1;
}
// 向前遍历链表
int list_show_forward(pLinklist H)
{
    if(empty(H))//只要不返回0  就表示是为空 或者表不存在
    {
        return -1;
    }
    pLinklist phead=H->prior;//头结点的前驱结点  是尾节点
    printf("从后往前遍历\n");
    while(phead!=H)
    {
        printf("%d\t",phead->data);
        phead=phead->prior;
    }
    printf("\n");
    return 0;

}
// 向后遍历链表
int list_show_back(pLinklist H)
{
    if(empty(H))//只要不返回0  就表示是为空 或者表不存在
    {
        return -1;
    }
    pLinklist phead=H->next;
    printf("从前往后遍历\n");
    while(phead!=H)
    {
        printf("%d\t",phead->data);
        phead=phead->next;
    }
    printf("\n");
    
}